/**
 * 注释解析工具类
 */
export class CommentUtils {
  /**
   * 从注释字符串中提取描述信息
   * @param comment 注释字符串
   * @returns 描述信息
   */
  public static extractDescription(comment: string | undefined): string {
    if (!comment) {
      return '';
    }
    
    // 移除注释符号和多余空格
    let description = comment
      .replace(/\/\*\*|\*\/|\*/g, '')  // 移除 /** */ 和 *
      .replace(/^\s*\/\/\s*/gm, '')    // 移除 // 
      .trim();
    
    // 移除 @xxx 标签行
    description = description.split('\n')
      .filter(line => !line.trim().startsWith('@'))
      .join('\n')
      .trim();
    
    return description;
  }

  /**
   * 从注释中提取指定标签的内容
   * @param comment 注释字符串
   * @param tagName 标签名称
   * @returns 标签内容数组
   */
  public static extractTags(comment: string | undefined, tagName: string): string[] {
    if (!comment) {
      return [];
    }
    
    const regex = new RegExp(`@${tagName}\\s+([^\\n@]*(?:\\n(?!\\s*@)[^\\n]*)*)?`, 'g');
    const matches = [...comment.matchAll(regex)];
    
    return matches.map(match => (match[1] || '').trim());
  }

  /**
   * 从注释中提取组件名称
   * @param comment 注释字符串
   * @returns 组件名称，如果不存在则返回null
   */
  public static extractComponentName(comment: string | undefined): string | null {
    if (!comment) {
      return null;
    }
    
    const nameTag = this.extractTags(comment, 'name')[0];
    if (nameTag) {
      return nameTag;
    }
    
    const componentTag = this.extractTags(comment, 'component')[0];
    if (componentTag) {
      return componentTag;
    }
    
    return null;
  }

  /**
   * 从注释中提取组件功能名称
   * @param comment 注释字符串
   * @returns 组件功能名称，如果不存在则返回null
   */
  public static extractComponentFunctionName(comment: string | undefined): string | null {
    if (!comment) {
      return null;
    }
    
    const functionTag = this.extractTags(comment, 'function')[0] 
      || this.extractTags(comment, 'functionality')[0];
    
    return functionTag || null;
  }

  /**
   * 从注释中提取属性信息
   * @param comment 注释字符串
   * @returns 属性类型，如果不存在则返回null
   */
  public static extractPropType(comment: string | undefined): string | null {
    if (!comment) {
      return null;
    }
    
    const typeTag = this.extractTags(comment, 'type')[0];
    return typeTag || null;
  }

  /**
   * 从注释中提取属性默认值
   * @param comment 注释字符串
   * @returns 属性默认值，如果不存在则返回null
   */
  public static extractPropDefaultValue(comment: string | undefined): string | null {
    if (!comment) {
      return null;
    }
    
    const defaultTag = this.extractTags(comment, 'default')[0];
    return defaultTag || null;
  }

  /**
   * 从注释中提取方法返回值类型
   * @param comment 注释字符串
   * @returns 方法返回值类型，如果不存在则返回null
   */
  public static extractReturnType(comment: string | undefined | null): string | null {
    if (!comment) {
      return null;
    }
    
    const returnTag = this.extractTags(comment, 'returns')[0] 
      || this.extractTags(comment, 'return')[0];
    
    if (!returnTag) {
      return null;
    }
    
    // 尝试提取返回类型 {Type} Description
    const typeMatch = returnTag.match(/^\s*\{([^}]+)\}(.*)/);
    if (typeMatch) {
      return typeMatch[1].trim();
    }
    
    return null;
  }

  /**
   * 从注释中提取方法返回值描述
   * @param comment 注释字符串
   * @returns 方法返回值描述，如果不存在则返回null
   */
  public static extractReturnDescription(comment: string | undefined | null): string | null {
    if (!comment) {
      return null;
    }
    
    const returnTag = this.extractTags(comment, 'returns')[0] 
      || this.extractTags(comment, 'return')[0];
    
    if (!returnTag) {
      return null;
    }
    
    // 尝试提取返回描述 {Type} Description
    const typeMatch = returnTag.match(/^\s*\{([^}]+)\}(.*)/);
    if (typeMatch) {
      return typeMatch[2].trim();
    }
    
    return returnTag.trim();
  }

  /**
   * 从注释中提取参数信息
   * @param comment 注释字符串
   * @returns 参数信息数组 [{ name, type, description }]
   */
  public static extractParams(comment: string | undefined): Array<{ name: string, type: string | null, description: string }> {
    if (!comment) {
      return [];
    }
    
    const paramTags = this.extractTags(comment, 'param');
    
    return paramTags.map(param => {
      // 提取格式: {Type} name - Description
      // 或格式: name {Type} - Description
      // 或格式: name - Description
      const paramMatch = param.match(/^\s*(?:\{([^}]+)\}\s+(\w+)|(\w+)(?:\s+\{([^}]+)\})?)(?:\s+-\s+(.*))?/);
      
      if (paramMatch) {
        if (paramMatch[1] && paramMatch[2]) {
          // 格式: {Type} name - Description
          return {
            name: paramMatch[2],
            type: paramMatch[1],
            description: (paramMatch[5] || '').trim()
          };
        } else if (paramMatch[3] && paramMatch[4]) {
          // 格式: name {Type} - Description
          return {
            name: paramMatch[3],
            type: paramMatch[4],
            description: (paramMatch[5] || '').trim()
          };
        } else if (paramMatch[3]) {
          // 格式: name - Description
          return {
            name: paramMatch[3],
            type: null,
            description: (paramMatch[5] || '').trim()
          };
        }
      }
      
      // 简单解析: 第一个单词作为名称，其余作为描述
      const parts = param.trim().split(/\s+/);
      return {
        name: parts[0] || '',
        type: null,
        description: parts.slice(1).join(' ')
      };
    });
  }

  /**
   * 提取注释中可能的枚举值
   * @param comment 注释字符串
   * @returns 枚举值数组
   */
  public static extractEnumValues(comment: string | undefined): string[] {
    if (!comment) {
      return [];
    }
    
    const valueTags = this.extractTags(comment, 'values') 
      || this.extractTags(comment, 'enum');
    
    if (valueTags.length === 0) {
      return [];
    }
    
    // 处理形如 'value1' | 'value2' | 'value3' 的格式
    const values: string[] = [];
    
    for (const valueTag of valueTags) {
      // 提取引号中的值
      const matches = [...valueTag.matchAll(/'([^']+)'|"([^"]+)"/g)];
      
      if (matches.length > 0) {
        for (const match of matches) {
          const value = match[1] || match[2];
          if (value) {
            values.push(value);
          }
        }
      } else {
        // 如果没有引号，则按逗号或竖线分隔
        const parts = valueTag.split(/[,|]/);
        for (const part of parts) {
          const trimmed = part.trim();
          if (trimmed) {
            values.push(trimmed);
          }
        }
      }
    }
    
    return values;
  }
} 